from processing.shape.description import Description
from processing.shape.color import light, color, dark
from pyprocessing import rect, fill, noStroke, stroke
from processing.model.flow_component import FlowComponent
from _collections import deque
from abc import abstractmethod


class ProcessingQueue(FlowComponent):
    
    def __init__(self):
        FlowComponent.__init__(self)
        self.__amount = 0
        self.__overflow = 0
        self.__overflow_text_offset_center = 30
        self.__items       = deque()
        self.configure()
        
        
    #values to configure subclasses
    def configure(self):
        self.x = 150
        self.y = 100
        self.__max         = 20
        self.__itemsize    = 16
        self.__margin      = 2
        self.__description = "Abstract queue"
        self.__bg_color    = light.red
        self.enter_position(60, 50)
        self.exit_position(self.w - 60, 50)
        
    @property
    def max(self):
        return self.__max

    @max.setter
    def max(self, value):
        self.__max = value
        
    @property
    def itemsize(self):
        return self.__itemsize

    @itemsize.setter
    def itemsize(self, value):
        self.__itemsize = value
        
    @property
    def margin(self):
        return self.__margin

    @margin.setter
    def margin(self, value):
        self.__margin = value
        
    @property
    def description(self):
        return self.__description

    @description.setter
    def description(self, value):
        self.__description = value
        
    @property
    def bg_color(self):
        return self.__bg_color

    @bg_color.setter
    def bg_color(self, value):
        self.__bg_color = value


        
    def on_added(self):
        FlowComponent.on_added(self)        
        self.add(Description(self.description, self.w / 2, 40, color.cyan, 10))
        offset_x = self.w - self.__overflow_text_offset_center
        self.__overflow_text = Description("", offset_x, self.h / 2 , color.black, 12)
        self.add(self.__overflow_text)
        
    def add_item(self, item_color=color.red):
        self.items.append(item_color)
        self.amount = len(self.items)
        
    def remove_first_item(self):
        self.items.popleft()
        self.amount = len(self.items)
   
    def update(self):
        FlowComponent.update(self)
        
    def draw(self):
        FlowComponent.draw(self)
        fill(*self.bg_color)
        stroke(*dark.green)
        rect(self.gx, self.gy, self.w, self.h); 
        self.draw_items()
    
    def draw_items(self):
        for index in range(0, self.draw_amount):
            x = self.gx + self.__margin + index*(self.__margin + 1) + index*self.__itemsize
            fill(*self.items[index])
            noStroke()
            rect(x, self.gy + self.__margin, self.__itemsize, self.__itemsize);
    
    @property
    def draw_amount(self):
        if(self.overflow > 0):
            return self.__max
        return self.amount
    
    @property
    def amount(self):
        return self.__amount
          
    @amount.setter   
    def amount(self, value):
        self.__amount = value
        if(value >= self.__max):
            self.overflow = value - self.__max
        
    @property   
    def overflow(self):
        return self.__overflow
          
    @overflow.setter   
    def overflow(self, value):
        self.__overflow = value
        self.__overflow_text.text = "+ " + str(value)
    
    @property
    def h(self):
        return self.__itemsize + self.__margin*2
    
    @property
    def w(self):
        overflow_offset = self.__overflow_text_offset_center*2
        return self.itemsize*self.max + (self.margin+1)*(self.max) + overflow_offset
    
    @property
    def items(self):
        return self.__items
    
    
    